package com.smartwebx.ha.dal.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Random;

import org.apache.commons.lang3.time.DateUtils;

import com.google.common.collect.Lists;

/**
 * 时间点判定方法，用于处理旬雨量和日雨量之间日期的混合判断
 * 
 * @author XX
 * 
 */
public class DatePoint {
	private static List<DateSection> dsBeanList = Lists.newArrayList();

	public static void main(String[] args) throws ParseException {
		Random r = new Random();
		for (int i = 0; i < 1000; i++) {
			int randomNum = r.nextInt((500 - 7) + 1) + 7;
			int randomNum2 = r.nextInt((500 - 7) + 1) + 7;
			int randomMonth = r.nextInt((11 - 0) + 1) + 0;
			int randomMonth2 = r.nextInt((11 - 0) + 1) + 0;

			GregorianCalendar calendar = new GregorianCalendar(2011,
					randomMonth, 1);
			Date date1 = calendar.getTime();
			calendar = new GregorianCalendar(2011, randomMonth2, 1);
			Date date2 = calendar.getTime();

			date1 = DateUtils.addDays(date1, randomNum);
			date2 = DateUtils.addDays(date2, randomNum2);

			if (date1.after(date2)) {
//				DatePoint.returnDatePoin(date1, date2);
			} else {
//				DatePoint.returnDatePoin(date2, date1);
			}
		}

//		Date startD = DateUtils.parseDate("2013-12-15", "yyyy-MM-d");
//		Date endD = DateUtils.parseDate("2013-12-30", "yyyy-MM-d");
//		List<DateSection> dsLists = DatePoint.returnDatePoin(startD, endD);
//
//		for (DateSection sdb : dsLists) {
//			System.out.println("type : " + sdb.getType());
//			if (sdb.getType() == 1) {
//				System.out.println("timeSec : " + sdb.getStartEnd()[0] + "--"
//						+ sdb.getStartEnd()[1]);
//			} else {
//				System.out.println("tenPoint : " + sdb.getTenPoint());
//			}
//		}
	}

	/**
	 * 根据时间段返回需要查询的时间段，用于旬(0)、日(1)、月(2) 查询
	 * 
	 * @return
	 * @throws ParseException
	 */
	public  List<DateSection> returnDatePoin(Date startDateStr,
			Date endDateStr) {
		dsBeanList.clear();

		// 开始结束的时间
		Calendar[] startEndCals = getStartEndCal(startDateStr, endDateStr);

		if (!checkDateSectionType(startEndCals[0], startEndCals[1])) {
			setDsBeanList(1, startEndCals, null);

			return dsBeanList;
		}

		// 开始与结束时间的差
		Integer endStarDiff = dayCompare(startEndCals[1].getTime(),
				startEndCals[0].getTime());
		// 开始日期
		Integer startDay = startEndCals[0].get(Calendar.DAY_OF_MONTH);
		// 结束时间
		Integer endDay = startEndCals[1].get(Calendar.DAY_OF_MONTH);

		// 旬日得开始和结束日期
		Calendar[] startEndTenPoint = new Calendar[2];
		// 记录旬的开始结束
		Calendar[] tenDayPoint = new Calendar[2];

		out1: for (int i = 0; i <= (endStarDiff / 10) + 1; i++) {

			// 第一次循环的判断
			if (i == 0) {
				// 开始时间判断
				if (startDay == 1 || startDay == 11 || startDay == 21) {
					startEndTenPoint[0] = startEndCals[0];

				} else {
					// 日雨量时间段
					Calendar[] rainFallCal = new Calendar[2];
					rainFallCal[0] = startEndCals[0];

					int newDay = 0;
					if (startDay < 11) {
						newDay = 10;
					} else if (startDay > 11 && startDay < 21) {
						newDay = 20;
					} else if (startDay > 21) {
						int nextMonth = startEndCals[0].get(Calendar.MONTH) + 1;
						Calendar c = new GregorianCalendar(
								startEndCals[0].get(Calendar.YEAR), nextMonth,
								0);

						newDay = c.get(Calendar.DAY_OF_MONTH);
					}

					Calendar newCal = new GregorianCalendar(
							startEndCals[0].get(Calendar.YEAR),
							startEndCals[0].get(Calendar.MONTH), newDay);
					if (newCal.before(startEndCals[1])) {
						rainFallCal[1] = newCal;
						setDsBeanList(1, rainFallCal, null);
					}

					newCal.set(Calendar.DAY_OF_MONTH, newDay + 1);
					startEndTenPoint[0] = newCal;
				}

				// 结束时间判断
				if (endDay == 1 || endDay == 11 || endDay == 21) {
					startEndTenPoint[1] = startEndCals[1];
				} //else {
					// 日雨量时间段
					Calendar[] rainFallCal = new Calendar[2];
					rainFallCal[1] = startEndCals[1];
					int newDay = 0;
					if (endDay < 11) {
						newDay = 1;
					} else if (endDay >= 11 && endDay < 21) {
						newDay = 11;
					} else if (endDay >= 21) {
						newDay = 21;
					}

					Calendar newCal = new GregorianCalendar(startEndCals[1]
							.get(Calendar.YEAR), startEndCals[1]
							.get(Calendar.MONTH), newDay);

					if (newCal.getTime().getTime() <= startEndCals[1].getTime()
							.getTime()) {
						rainFallCal[0] = newCal;
						setDsBeanList(1, rainFallCal, null);
					}

					newCal.set(Calendar.DAY_OF_MONTH, newDay);
					startEndTenPoint[1] = newCal;
				//}

				tenDayPoint[0] = startEndTenPoint[0];
			}

			// 需要克隆啊。。。。。。。。。。。。。。
			Calendar nextTenPoint = (Calendar) tenDayPoint[0].clone();

			if (nextTenPoint.get(Calendar.DAY_OF_MONTH) < 21) {
				nextTenPoint.set(Calendar.DAY_OF_MONTH,
						nextTenPoint.get(Calendar.DAY_OF_MONTH) + 10);
			} else {
				nextTenPoint.set(Calendar.MONTH,
						nextTenPoint.get(Calendar.MONTH) + 1);

				nextTenPoint.set(Calendar.DAY_OF_MONTH, 1);
			}

			if (nextTenPoint.getTimeInMillis() < startEndTenPoint[1]
					.getTimeInMillis()) {

				tenDayPoint[1] = nextTenPoint;

				setDsBeanList(0, null, tenDayPoint);

			} else if (nextTenPoint.getTimeInMillis() == startEndTenPoint[1]
					.getTimeInMillis()) {

				tenDayPoint[1] = nextTenPoint;
				setDsBeanList(0, null, tenDayPoint);
				break out1;
			}

			tenDayPoint[0] = tenDayPoint[1];
		}

		List<DateSection> dsBeanListCopy = new ArrayList<DateSection>();
		dsBeanListCopy.addAll(dsBeanList);

		List<DateSection> monthDSBList = new ArrayList<DateSection>();

		// 判断旬过程是否为干净的
		Boolean notObey = true;
		Integer dsBListIndex = 0;
		for (DateSection dsb : dsBeanList) {
			if (dsb.getType() == 0) {

				dsBListIndex++;

				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d HH:mm");
				Date tenD = null;
				try {
					tenD = sdf.parse(dsb.getTenPoint());
				} catch (ParseException e) {
					e.printStackTrace();
				}
				Calendar tenCal = Calendar.getInstance();
				tenCal.setTime(tenD);

				Integer dayNum = tenCal.get(Calendar.DAY_OF_MONTH);

				monthDSBList.add(dsb);

				if (dsBListIndex == 1 && dayNum == 11) {
					notObey = false;
				}

				if (notObey) {
					if ((dsBListIndex == 1 || dsBListIndex == 2)
							&& (dayNum == 21 || dayNum == 1)) {
						if (monthDSBList.size() < 3) {
							monthDSBList.clear();
						}
					}
				}

				if (dayNum == 1) {
					if (monthDSBList.size() == 3) {

						dsBeanListCopy.removeAll(monthDSBList);

						DateSection oDsb = new DateSection();
						oDsb.setType(2);
						oDsb.setTenPoint(monthDSBList.get(
								monthDSBList.size() - 1).getTenPoint());
						dsBeanListCopy.add(oDsb);

						monthDSBList.clear();
					}
				}
			}
		}

		dsBeanList = dsBeanListCopy;

		return dsBeanList;
	}

	/**
	 * 获得开始结束日期时间段
	 * 
	 * @param startDateStr
	 * @param endDateStr
	 * @return
	 */
	/*二期*/
	private static Calendar[] getStartEndCal(Date startDateStr, Date endDateStr) {
		Integer[] startDateInt = getDateInt(startDateStr);
		Integer[] endDateInt = getDateInt(endDateStr);

		Calendar startCal = new GregorianCalendar(startDateInt[0],
				startDateInt[1] - 1, startDateInt[2]);
		Calendar endCal = new GregorianCalendar(endDateInt[0],
				endDateInt[1] - 1, endDateInt[2]);//二期-1

		Calendar[] startEndCal = { startCal, endCal };

		return startEndCal;
	}
	/*一期代码*/
	/*private static Calendar[] getStartEndCal(Date startDateStr, Date endDateStr) {
		Integer[] startDateInt = getDateInt(startDateStr, "s");
		Integer[] endDateInt = getDateInt(endDateStr, "e");

		Calendar startCal = new GregorianCalendar(startDateInt[0],
				startDateInt[1] - 1, startDateInt[2]);
		Calendar endCal = new GregorianCalendar(endDateInt[0],
				endDateInt[1] - 1, endDateInt[2]);

		Calendar[] startEndCal = { startCal, endCal };

		return startEndCal;
	}*/

	/**
	 * 填充日期范围与旬月列表
	 * 
	 * @param type
	 * @param startEndCals
	 * @param startEndTenPoint
	 */
	private static void setDsBeanList(Integer type, Calendar[] startEndCals,
			Calendar[] startEndTenPoint) {
		DateSection dsBean = new DateSection();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d");

		if (type == 1) {
			String[] startEnds = new String[2];
			startEnds[0] = sdf.format(startEndCals[0].getTime());
			startEnds[1] = sdf.format(startEndCals[1].getTime());
			dsBean.setStartEnd(startEnds);

		} else if (type == 0) {
			// int year = startEndTenPoint[0].get(Calendar.YEAR);
			// int month = startEndTenPoint[0].get(Calendar.MONTH);
			// int day = startEndTenPoint[1].get(Calendar.DAY_OF_MONTH);
			// int tenSign = 0;
			// if (day == 11) {
			// tenSign = 1;
			// } else if (day == 21) {
			// tenSign = 2;
			// } else if (day == 1) {
			// tenSign = 3;
			// month = month - 1;
			// if (month == 0) {
			// month = 12;
			// year = year - 1;
			// }
			// }

			// Calendar tenCal = new GregorianCalendar(year, month, day);
			// if (day == 21){
			// tenCal.set(Calendar.MONTH, tenCal.get(Calendar.MONTH) + 1);
			// tenCal.set(Calendar.DAY_OF_MONTH, 1);
			// }
			String tenPoint = sdf.format(startEndTenPoint[1].getTime())
					+ " 08:00:00";

			dsBean.setTenPoint(tenPoint);
		}
		dsBean.setType(type);

		dsBeanList.add(dsBean);
	}

	/**
	 * 判断时间段范围是否包含旬月时间
	 * 
	 * @return
	 */
	private static Boolean checkDateSectionType(Calendar startCal,
			Calendar endCal) {
		int tenPoint = 0;
		int startDay = startCal.get(Calendar.DAY_OF_MONTH);
		int startMonth = startCal.get(Calendar.MONTH);
		int startYear = startCal.get(Calendar.YEAR);

		int newDay = 0;
		Calendar newCal = null;

		if (startDay == 1 || startDay == 11 || startDay == 21) {
			tenPoint++;
			newDay = startDay + 10;

			newCal = new GregorianCalendar(startYear, startMonth, newDay);
		} else {
			int newMonth = startMonth;
			if (startDay > 1 && startDay < 11) {
				newDay = 11;
			} else if (startDay > 11 && startDay < 21) {
				newDay = 21;
			} else if (startDay > 21) {
				newMonth = newMonth + 1;
				newDay = 1;
			}
			newCal = new GregorianCalendar(startYear, newMonth, newDay);
			if (endCal.after(newCal))
				tenPoint++;

			newCal.set(Calendar.DAY_OF_MONTH, newDay + 10);
		}

		if (newCal.before(endCal))
			tenPoint++;

		return tenPoint == 2;
	}

	/**
	 * 第一个日期与第二个日期比较
	 * 
	 * @param firstDate
	 * @param secondDate
	 * @return
	 */
	private static Integer dayCompare(Date firstDate, Date secondDate) {
		int day = (int) ((firstDate.getTime() - secondDate.getTime()) / 3600 / 24 / 1000);
		return day;
	}

	/**
	 * 根据日期返回 年 月 日
	 * 
	 * @return
	 */
	/*二期修改*/
	private static Integer[] getDateInt(Date source) {
		Calendar sourceCal = Calendar.getInstance();
		sourceCal.setTime(source);

		int year = sourceCal.get(Calendar.YEAR);
		int month = sourceCal.get(Calendar.MONTH) + 1;
		int dayOfMonth = sourceCal.get(Calendar.DAY_OF_MONTH);

		Integer[] dateInt = { year, month, dayOfMonth };

		return dateInt;
	}
	/*一期代码*/
	/*private static Integer[] getDateInt(Date source, String type) {
		Calendar sourceCal = Calendar.getInstance();
		sourceCal.setTime(source);

		int year = sourceCal.get(Calendar.YEAR);
		int month = sourceCal.get(Calendar.MONTH) + 1;
		int dayOfMonth = sourceCal.get(Calendar.DAY_OF_MONTH);

		Integer[] dateInt = { year, month,
				type.equals("s") ? dayOfMonth : (dayOfMonth + 1) };

		return dateInt;
	}*/

}
